<template>
  <div v-if="showMonitor" class="performance-monitor">
    <div class="monitor-header">
      <h4>性能监控</h4>
      <el-button size="small" text @click="toggleMonitor">
        <el-icon><Close /></el-icon>
      </el-button>
    </div>
    
    <div class="monitor-content">
      <div class="metric">
        <span class="label">FPS:</span>
        <span class="value" :class="getFpsClass(fps)">{{ fps }}</span>
      </div>
      
      <div class="metric">
        <span class="label">内存:</span>
        <span class="value">{{ memoryUsage }}MB</span>
      </div>
      
      <div class="metric">
        <span class="label">拖拽延迟:</span>
        <span class="value" :class="getLatencyClass(dragLatency)">{{ dragLatency }}ms</span>
      </div>
      
      <div class="metric">
        <span class="label">渲染时间:</span>
        <span class="value">{{ renderTime }}ms</span>
      </div>
    </div>
    
    <!-- FPS图表 -->
    <div class="fps-chart">
      <canvas ref="chartCanvas" width="200" height="60"></canvas>
    </div>
  </div>
  
  <!-- 性能监控开关 -->
  <div v-else class="monitor-toggle">
    <el-button size="small" @click="toggleMonitor">
      <el-icon><View /></el-icon>
      性能
    </el-button>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, nextTick } from 'vue'
import { Close, View } from '@element-plus/icons-vue'

// 响应式数据
const showMonitor = ref(false)
const fps = ref(60)
const memoryUsage = ref(0)
const dragLatency = ref(0)
const renderTime = ref(0)
const chartCanvas = ref(null)

// FPS历史数据
const fpsHistory = ref([])
const maxHistoryLength = 50

// 性能监控变量
let lastTime = performance.now()
let frameCount = 0
let fpsInterval = null
let memoryInterval = null
let chartContext = null

// 方法
const toggleMonitor = () => {
  showMonitor.value = !showMonitor.value
  
  if (showMonitor.value) {
    startMonitoring()
    nextTick(() => {
      initChart()
    })
  } else {
    stopMonitoring()
  }
}

const startMonitoring = () => {
  // FPS监控
  fpsInterval = setInterval(() => {
    const currentTime = performance.now()
    const deltaTime = currentTime - lastTime
    
    if (deltaTime >= 1000) {
      fps.value = Math.round((frameCount * 1000) / deltaTime)
      
      // 更新FPS历史
      fpsHistory.value.push(fps.value)
      if (fpsHistory.value.length > maxHistoryLength) {
        fpsHistory.value.shift()
      }
      
      frameCount = 0
      lastTime = currentTime
      
      updateChart()
    }
    
    frameCount++
  }, 100)
  
  // 内存监控
  if (performance.memory) {
    memoryInterval = setInterval(() => {
      memoryUsage.value = Math.round(performance.memory.usedJSHeapSize / 1024 / 1024)
    }, 1000)
  }
  
  // 渲染时间监控
  const observer = new PerformanceObserver((list) => {
    const entries = list.getEntries()
    entries.forEach((entry) => {
      if (entry.entryType === 'measure') {
        renderTime.value = Math.round(entry.duration)
      }
    })
  })
  
  try {
    observer.observe({ entryTypes: ['measure'] })
  } catch (e) {
    console.warn('Performance Observer not supported')
  }
}

const stopMonitoring = () => {
  if (fpsInterval) {
    clearInterval(fpsInterval)
    fpsInterval = null
  }
  
  if (memoryInterval) {
    clearInterval(memoryInterval)
    memoryInterval = null
  }
}

const initChart = () => {
  if (!chartCanvas.value) return
  
  chartContext = chartCanvas.value.getContext('2d')
  chartContext.fillStyle = '#f5f7fa'
  chartContext.fillRect(0, 0, 200, 60)
}

const updateChart = () => {
  if (!chartContext || fpsHistory.value.length === 0) return
  
  // 清空画布
  chartContext.fillStyle = '#f5f7fa'
  chartContext.fillRect(0, 0, 200, 60)
  
  // 绘制FPS曲线
  chartContext.strokeStyle = '#409EFF'
  chartContext.lineWidth = 2
  chartContext.beginPath()
  
  const width = 200
  const height = 60
  const maxFps = 60
  const stepX = width / maxHistoryLength
  
  fpsHistory.value.forEach((fpsValue, index) => {
    const x = index * stepX
    const y = height - (fpsValue / maxFps) * height
    
    if (index === 0) {
      chartContext.moveTo(x, y)
    } else {
      chartContext.lineTo(x, y)
    }
  })
  
  chartContext.stroke()
  
  // 绘制基准线
  chartContext.strokeStyle = '#e4e7ed'
  chartContext.lineWidth = 1
  chartContext.setLineDash([2, 2])
  
  // 60 FPS线
  chartContext.beginPath()
  chartContext.moveTo(0, 0)
  chartContext.lineTo(width, 0)
  chartContext.stroke()
  
  // 30 FPS线
  chartContext.beginPath()
  chartContext.moveTo(0, height / 2)
  chartContext.lineTo(width, height / 2)
  chartContext.stroke()
  
  chartContext.setLineDash([])
}

const getFpsClass = (fpsValue) => {
  if (fpsValue >= 55) return 'good'
  if (fpsValue >= 30) return 'warning'
  return 'poor'
}

const getLatencyClass = (latency) => {
  if (latency <= 16) return 'good'
  if (latency <= 33) return 'warning'
  return 'poor'
}

// 拖拽延迟测量
const measureDragLatency = () => {
  const start = performance.now()
  
  return () => {
    const end = performance.now()
    dragLatency.value = Math.round(end - start)
  }
}

// 暴露方法给父组件
defineExpose({
  measureDragLatency
})

onMounted(() => {
  // 默认不开启监控
})

onUnmounted(() => {
  stopMonitoring()
})
</script>

<style scoped>
.performance-monitor {
  position: fixed;
  top: 80px;
  right: 20px;
  width: 220px;
  background: white;
  border: 1px solid #e4e7ed;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  z-index: 1000;
  font-size: 12px;
}

.monitor-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 12px;
  border-bottom: 1px solid #e4e7ed;
  background: #f8f9fa;
}

.monitor-header h4 {
  margin: 0;
  font-size: 13px;
  color: #303133;
}

.monitor-content {
  padding: 12px;
}

.metric {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
}

.label {
  color: #606266;
}

.value {
  font-weight: 600;
  font-family: monospace;
}

.value.good {
  color: #67C23A;
}

.value.warning {
  color: #E6A23C;
}

.value.poor {
  color: #F56C6C;
}

.fps-chart {
  padding: 8px 12px;
  border-top: 1px solid #e4e7ed;
}

.monitor-toggle {
  position: fixed;
  top: 80px;
  right: 20px;
  z-index: 1000;
}

canvas {
  border: 1px solid #e4e7ed;
  border-radius: 4px;
}
</style>
